/*
 * @lc app=leetcode.cn id=51 lang=cpp
 *
 * [51] N 皇后
 *
 * https://leetcode.cn/problems/n-queens/description/
 *
 * algorithms
 * Hard (73.94%)
 * Likes:    2032
 * Dislikes: 0
 * Total Accepted:    366.9K
 * Total Submissions: 496K
 * Testcase Example:  '4'
 *
 * 按照国际象棋的规则，皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。
 * 
 * n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上，并且使皇后彼此之间不能相互攻击。
 * 
 * 给你一个整数 n ，返回所有不同的 n 皇后问题 的解决方案。
 * 
 * 
 * 
 * 每一种解法包含一个不同的 n 皇后问题 的棋子放置方案，该方案中 'Q' 和 '.' 分别代表了皇后和空位。
 * 
 * 
 * 
 * 示例 1：
 * 
 * 
 * 输入：n = 4
 * 输出：[[".Q..","...Q","Q...","..Q."],["..Q.","Q...","...Q",".Q.."]]
 * 解释：如上图所示，4 皇后问题存在两个不同的解法。
 * 
 * 
 * 示例 2：
 * 
 * 
 * 输入：n = 1
 * 输出：[["Q"]]
 * 
 * 
 * 
 * 
 * 提示：
 * 
 * 
 * 1 <= n <= 9
 * 
 * 
 * 
 * 
 */

// @lc code=start
class Solution {
public:
    bool IsValid(const vector<string>& chessboard, int n, int curRow) {
        //列上是否有皇后
        for (int i = 0; i < curRow; i++)
            if (chessboard[i][n] == 'Q')
                return false;

        //45 度
        for (int r = curRow, c = n; r >= 0 && c >= 0; r--, c--)
            if (chessboard[r][c] == 'Q')
                return false;

        //135 度
        for (int r = curRow, c = n; r >= 0 && c < chessboard.size(); r--, c++)
            if (chessboard[r][c] == 'Q')
                return false;

        return true;
    }

    void BackTracking(vector<vector<string>>& result, vector<string>& chessboard, int curRow) {
        if (curRow == chessboard.size()) {
            result.push_back(chessboard);
            return;
        }

        for (int i = 0; i < chessboard.size(); i++) {
            if (IsValid(chessboard, i, curRow)) {
                chessboard[curRow][i] = 'Q';
                BackTracking(result, chessboard, curRow + 1);
                chessboard[curRow][i] = '.';
            }

        }
    }

    vector<vector<string>> solveNQueens(int n) {
        //检索方式类似 17.电话号码字母组合
        //需要控制深度

        //在确定 n 的情况下, 暴力搜索表示有多少层 n 的循环
        //当 n 为变量时, 需要使用回溯法进行控制 (写不出变化嵌套的循环)
        //所以控制深度至关重要

        vector<vector<string>> result;

        string chess(n, '.');
        vector<string> chessboard(n, chess); //path

        BackTracking(result, chessboard, 0);
        return result;
    }
};
// @lc code=end

